#include "multiselectcombobox.h"
#include <QWidget>
#include <QLabel>
#include <QDebug>
#include <QToolTip>
#include <QPainter>
#include <memory>
#include <QRandomGenerator>


CheckBoxWidget::CheckBoxWidget(QWidget *parent) : QWidget(parent),
    m_check_box(NULL), m_label(NULL)
{
    m_check_box = new QCheckBox(this);
    m_label = new QLabel("hold place ..", this);
    m_label->installEventFilter(this);
    setColor();

    m_spacer = new QSpacerItem(20, 20, QSizePolicy::Expanding, QSizePolicy::Minimum);
    m_layout = new QHBoxLayout();
    m_layout->addWidget(m_check_box);
    m_layout->addItem(m_spacer);
    m_layout->addWidget(m_label);
    this->setLayout(m_layout);
    connect(m_check_box, &QCheckBox::stateChanged, this, &CheckBoxWidget::stateChanged);
}
CheckBoxWidget::~CheckBoxWidget()
{
    /* 手动调用布局器的析构函数会导致冲突 */
//    if (m_spacer) {
//        delete m_spacer;
//        m_spacer = NULL;
//    }
//    if (m_layout) {
//        delete m_layout;
//        m_layout = NULL;
//    }
}
void CheckBoxWidget::setText(const QString &text)
{
    m_check_box->setText(text);
}
QString CheckBoxWidget::getText() const
{
    return m_check_box->text();
}
bool CheckBoxWidget::isChecked() const
{
    return m_check_box->isChecked();
}
void CheckBoxWidget::setColor(const QColor color)
{

    int style = 0;
    while (!style) {
        style = std::rand() % 6;
    }
    m_pen.setStyle((Qt::PenStyle)style);
    m_pen.setWidth(4);
    if(color == Qt::color0) {
        m_pen.setColor(QColor(QRandomGenerator::global()->bounded(256),
                              QRandomGenerator::global()->bounded(256),
                              QRandomGenerator::global()->bounded(256)));
    }
    else {
        m_pen.setColor(color);
    }
}
QColor CheckBoxWidget::getColor() const
{
    return m_pen.color();
}

QPen CheckBoxWidget::getPen() const
{
    return m_pen;
}
void CheckBoxWidget::setSize(int width, int height)
{
    this->setFixedSize(width, height);
}
bool CheckBoxWidget::eventFilter(QObject *obj, QEvent *e)
{
    if (obj == m_label && e->type() == QEvent::Paint) {
        std::unique_ptr<QPainter> painter(new QPainter(m_label));
        painter->setPen(m_pen);
        painter->drawLine(2, m_label->size().height() / 2,
                          150, m_label->size().height() / 2);
        return true;
    }
    return QWidget::eventFilter(obj, e);
}


/* 主功能类 */
MultiSelectComboBox::MultiSelectComboBox(QWidget *parent) : QComboBox(parent)
{
    m_list_widget = new QListWidget(this);
    m_list_widget->setViewMode(QListView::ListMode);
    this->setModel(m_list_widget->model());
    this->setView(m_list_widget);

    m_edit = new QLineEdit(this);
    m_edit->setReadOnly(true);
    m_edit->setToolTip(tr("点击下拉按键展开列表"));
    this->setLineEdit(m_edit);
}
MultiSelectComboBox::~MultiSelectComboBox()
{
    QListWidgetItem *list_item = NULL;
    CheckBoxWidget *check_widget = NULL;
    for (int row = 0; row < m_list_widget->count(); ++row) {
        list_item = m_list_widget->item(0);
        check_widget = (CheckBoxWidget *)m_list_widget->itemWidget(list_item);
        delete check_widget;
        list_item = m_list_widget->takeItem(0);
        delete list_item;
    }
    if (m_edit) delete m_edit;
}

int MultiSelectComboBox::addItem(const QString &item, const QColor color)
{
    CheckBoxWidget *check_box = new CheckBoxWidget(this);
    check_box->setText(item);
    check_box->setColor(color);
    connect(check_box, &CheckBoxWidget::stateChanged, this, &MultiSelectComboBox::itemClicked);

    QListWidgetItem *list_item = new QListWidgetItem();
    m_list_widget->addItem(list_item);
    m_list_widget->setItemWidget(list_item, check_box);

    if (size().height() < 50) {
        check_box->setSize(size().width(), 50);
        this->setItemData(m_list_widget->count() - 1,
                          QSize(size().width(), 50),
                          Qt::SizeHintRole);
    }
    else {
        check_box->setSize(size().width(), size().height());
        this->setItemData(m_list_widget->count() - 1,
                          QSize(size().width(), size().height()),
                          Qt::SizeHintRole);
    }
    return 0;
}

int MultiSelectComboBox::addItems(const QStringList &items)
{
    for(auto item : items) {
        addItem(item);
    }
    return 0;
}
QStringList MultiSelectComboBox::currentItems() const
{
    QStringList temp;
    for (int i = 0; i < m_list_widget->count(); ++i) {
        auto item = (CheckBoxWidget *)m_list_widget->itemWidget(m_list_widget->item(i));
        if (item->isChecked()) {
            temp.push_back(item->getText());
        }
    }
    return temp;
}
int MultiSelectComboBox::getItemAttr(const QString name, QPen &pen)
{
    for (int i = 0; i < m_list_widget->count(); ++i) {
        auto item = (CheckBoxWidget *)m_list_widget->itemWidget(m_list_widget->item(i));
            if (item->getText() == name) {
                pen = item->getPen();
                return 0;
        }
    }
    return -1;
}

void MultiSelectComboBox::setPlaceHolderText(const QString label)
{
    m_edit->setPlaceholderText(label);
}

void MultiSelectComboBox::itemClicked()
{
    CheckBoxWidget *check_box = (CheckBoxWidget *)sender();
    emit selectedChange(check_box->getText(), check_box->isChecked());
}

void MultiSelectComboBox::clear()
{
    for (int i = 0; i < m_list_widget->count(); ++i) {
        auto item = (CheckBoxWidget *)m_list_widget->itemWidget(m_list_widget->item(i));
        if (item)  {
            delete item;
            item = NULL;
        }
        delete m_list_widget->item(i);
    }
    m_list_widget->clear();
}


